package com.edfu.core.commons.persistence.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.edfu.core.commons.persistence.api.IRatingPersistence;
import com.edfu.core.commons.persistence.entity.RatingEntity;
import com.edfu.core.identitymgt.persistence.entity.UserEntity;

public class RatingPersistenceImpl implements IRatingPersistence {
	
	private static Logger logger = LoggerFactory.getLogger(RatingPersistenceImpl.class);
	
	private EntityManager entityManager;
	
	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	@Override
	public RatingEntity addRating(RatingEntity ratingEntity) {
		return entityManager.merge(ratingEntity);
	}

	@Override
	public double getMeanRating(long objectId, String objectType) {
		logger.debug("Getting mean rating for ObjectId : " + objectId + " : ObjectType : " + objectType);
		Query query = entityManager.createQuery("select avg(r.score) from RatingEntity r where r.objectId = :objectId and r.objectType = :objectType");
		query.setParameter("objectId", objectId);
		query.setParameter("objectType", objectType);
		
		return (Double) query.getSingleResult();
	}

	@Override
	public long getRatingCount(long objectId, String objectType) {
		Query query = entityManager.createQuery("select count(*) from RatingEntity r where r.objectId = :objectId and r.objectType = :objectType");
		query.setParameter("objectId", objectId);
		query.setParameter("objectType", objectType);
		
		return (Long) query.getSingleResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<RatingEntity> getRatings(long objectId, String objectType) {
		Query query = entityManager.createQuery("select r from RatingEntity r where r.objectId = :objectId and r.objectType = :objectType");
		query.setParameter("objectId", objectId);
		query.setParameter("objectType", objectType);
		
		return query.getResultList();
	}

	@Override
	public RatingEntity getUserRating(UserEntity userEntity, long objectId, String objectType) {
		Query query = entityManager.createQuery("select r from RatingEntity r where r.user = :user and r.objectId = :objectId and r.objectType = :objectType");
		query.setParameter("user", userEntity);
		query.setParameter("objectId", objectId);
		query.setParameter("objectType", objectType);
		
		return (RatingEntity) query.getSingleResult();
	}

}
